import { useIdle } from '@vueuse/core'
import type {
  NotificationHandle,
} from 'element-plus'
import {
  ElNotification,
} from 'element-plus'
import type { WatchStopHandle } from 'vue'

const projectVersion = 'sysinteg_project_version'

/**
 * ### 通过对比入口文件hash值，提醒用户服务器更新，建议重新登录
 * @description 仅在生产环境生效
 */
export function useServiceUpdate() {
  let mainDom: HTMLScriptElement | null = null
  let newHash: string | undefined = ''
  let oldHash: string | null = ''
  let watchStopHandle: WatchStopHandle | null = null
  const notificationTuple: NotificationHandle[] = []

  const init = () => {
    getMainScript()
    getNewHash()
    getOldHash()
  }

  const getMainScript = () => {
    mainDom = document.querySelector(
      'script[type="module"][src*="/js/index-"]',
    )
  }

  const getNewHash = () => {
    newHash = mainDom?.src?.replace?.(
      /.+-(.{8})\.js/g,
      '$1',
    )
  }
  const getOldHash = () => {
    oldHash = localStorage.getItem(projectVersion)
  }
  const isPro = () => {
    return import.meta.env.VITE_ENV === 'production'
  }

  const verify = () => {
    const { logout } = useUserStore()
    if (notificationTuple.length !== 0)
      return

    const m = ElNotification({
      title: '警告',
      message: h('div', { style: 'color: teal' }, [
        '服务器更新，建议重新登录，避免出现问题!',
        h(
          'span',
          {
            class:
              'text-blue c-pointer margin-left-sm fs-14',
            onClick: func,
          },
          '重新登录',
        ),
      ]),
      onClose() {
        notificationTuple.length = 0
      },
      type: 'warning',
    })
    notificationTuple.push(m)
    function func() {
      logout()
      notificationTuple[0]!.close?.()
      watchStopHandle?.()
    }
  }
  const watchUpdate = () => {
    if (!isPro())
      return
    init()
    const bol = newHash === oldHash
    if (bol)
      return
    verify()
    const { idle } = useIdle(10000)

    watchStopHandle = watch(
      () => idle.value,
      (v: boolean, pv: boolean) => {
        if (!pv && v)
          return
        verify()
      },
    )
  }

  const updateProjectVersion = () => {
    if (!isPro())
      return
    init()
    localStorage.setItem(projectVersion, newHash ?? '')
  }

  return {
    updateProjectVersion,
    watchUpdate,
  }
}
